/* This file contains the entry point for the program
*
*
*/

#include "sudoku.h"
#include "fifo.h"
#include "backtrack.h"
#include "scheduler.h"

unsigned long long begin_time;
int nt;
Statistics stat;

int main(int argc, char * argv[])
{
	int i;
	pthread_t * threads;
	ProcArgs_T * pargs; 
	ProcStatus_T pstat;
	Stack s = newStack();
	char input[12][GRID_SIZE * GRID_SIZE + 1] =
	{"4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......",
		"6.4..83.9...3.2.78.829..4.5.6..9..34...2.3...73..1..8.5.3..486.42.6.1...8.65..2..",
		"8.1...3.6.2.641.7.6.......2.3.8.4.9..1.....8..5.2.9.4.3.......1.9.387.6.4.7...9.8",
		"52...6.........7.13...........4..8..6......5...........418.........3..2...87.....",
		"6.....8.3.4.7.................5.4.7.3..2.....1.6.......2.....5.....8.6......1....",
		"48.3............71.2.......7.5....6....2..8.............1.76...3.....4......5....",
		"....14....3....2...7..........9...3.6.1.............8.2.....1.4....5.6.....7.8...",
		"......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.",
		"6.2.5.........3.4..........43...8....1....2........7..5..27...........81...6.....",
		".524.........7.1..............8.2...3.....6...9.5.....1.6.3...........897........",
		".................................................................................",
		"11..............................................................................."};

	Grid grid = newGrid();
	nt = atoi(argv[2]);
	
	threads = (pthread_t *) malloc(sizeof(pthread_t) * nt);
	pargs = (ProcArgs_T *) malloc(sizeof(ProcArgs_T) * nt);
	
	populateGrid(input[atoi(argv[1])], grid);
	printf("puzzle\n");
	prtGrid(grid, 1);
	
	//printf("Bitcounts\n");
	//prtGridBitcount(grid);	
	//prtGrid(grid, 1);	
	//printf("Bitcounts after markup\n");
	//prtGridBitcount(grid);
	
	// Must markup grid before calling backtrack
	markup(grid);

	printf("pbt:\n");

	pBTInput in_args = (pBTInput) malloc(sizeof(BTInput));
	in_args->s = s;
	in_args->g = grid;
	
	for(i = 0; i < nt; i++)
	{
		stat.dequeue_time[i] = 0;
		stat.num_dequeue[i] = 0;
		stat.processing_time[i] = 0;
		stat.schedule_overhead[i] = 0;
	}
	stat.enqueue_time = 0;
	stat.num_enqueue = 0;

	begin_time = rdtsc();
	schedule(s, &pBacktrack, (void *)in_args);
	launchProcessors(nt, threads, &pstat, pargs, s);
	printf("debug 0\n");
	collectProcessors(nt, threads, &pstat);
	
	delStack(s);

	printf("enqueue: %lld %lld\n", stat.enqueue_time, stat.num_enqueue);
	for (i = 0; i < nt; i++)
	{
		printf("t:%d\t d%lld nd%lld p%lld s%lld\n", i, stat.dequeue_time[i],
		stat.num_dequeue[i], stat.processing_time[i],
		stat.schedule_overhead[i]);
	}	
	return 0;  
}

